interface _CU_ {
    /**
     * 取类型
     * @param obj 对象
     * @param detail false: 取类型;
     * @returns 类型
     */
    typeof(obj: any, detail?: false): Ttypeof;
    /**
     * 取类型
     * @param obj 对象
     * @param detail true: 取详细类型;
     * @returns 详细类型
     */
    typeof(obj: any, detail: true): Ttypeof_detail;
}
{
    Object.defineProperty(_CU_.prototype, 'typeof', {
        writable: false,
        configurable: false,
        enumerable: false,
        value: (obj: any, detail?: boolean): Ttypeof | Ttypeof_detail => {
            if (detail === true) {
                switch (typeof obj) {
                    case 'undefined': {
                        return { type: Etype.undefined, detail: Etypedetail.undefined };
                    } break;
                    case 'symbol': {
                        return { type: Etype.symbol, detail: Etypedetail.symbol };
                    } break;
                    case 'bigint': {
                        if (obj === BigInt0) { return { type: Etype.bigint, detail: Etypedetail.bigint_zero }; }
                        return { type: Etype.bigint, detail: obj > 0 ? Etypedetail.bigint_positive : Etypedetail.bigint_negative };
                    } break;
                    case 'number': {
                        if (Number.isNaN(obj)) { return { type: Etype.number, detail: Etypedetail.number_NaN }; }
                        if (!Number.isFinite(obj)) { return { type: Etype.number, detail: obj > 0 ? Etypedetail.number_positive_Infinity : Etypedetail.number_negative_Infinity }; }
                        if (Number.isInteger(obj)) {
                            if (obj === 0) { return { type: Etype.number, detail: Etypedetail.number_zero }; }
                            return { type: Etype.number, detail: obj > 0 ? Etypedetail.number_positive_Integer : Etypedetail.number_negative_Integer };
                        }
                        return { type: Etype.number, detail: obj > 0 ? Etypedetail.number_positive_Decimal : Etypedetail.number_negative_Decimal };
                    } break;
                    case 'boolean': {
                        return { type: Etype.boolean, detail: obj ? Etypedetail.boolean_true : Etypedetail.boolean_false };
                    } break;
                    case 'string': {
                        if (obj === '') { return { type: Etype.string, detail: Etypedetail.string_empty }; }
                        if (obj.trim() === '') { return { type: Etype.string, detail: Etypedetail.string_blank }; }
                        return { type: Etype.string, detail: Etypedetail.string };
                    } break;
                    case 'function': {
                        return { type: Etype.function, detail: Etypedetail.function };
                    } break;
                    case 'object': {
                        if (obj === null) {
                            return { type: Etype.null, detail: Etypedetail.null };
                        }

                        if (obj === DEFAULT) {
                            return { type: Etype.DEFAULT, detail: Etypedetail.DEFAULT };
                        }

                        if (typeof obj.constructor === 'undefined') {
                            return { type: Etype.NULLOBJ, detail: Etypedetail.NULLOBJ };
                        }

                        if (obj.constructor === Object) {
                            // if (Object.getPrototypeOf(obj) === Object.prototype) {// 字面量对象
                            // } else {// 通过Object.create创建的对象
                            // }
                            return { type: Etype.obj, detail: Object.keys(obj).length === 0 ? Etypedetail.obj_empty : Etypedetail.obj };
                        }

                        if (Array.isArray(obj)) {
                            return { type: Etype.array, detail: obj.length === 0 ? Etypedetail.array_empty : Etypedetail.array };
                        }

                        if (obj instanceof HTMLElement) {
                            return { type: Etype.HTMLElement, detail: obj.constructor.name as Etypedetail };// 此处强制绕过，但其实返回值在Etypedetail中没有直接定义。
                        }

                        return { type: obj.constructor.name, detail: Object.prototype.toString.call(obj) as Etypedetail };// 此处强制绕过，但其实返回值在Etypedetail中没有直接定义。
                    } break;
                }
            } else {
                switch (typeof obj) {
                    case 'undefined': { return Etype.undefined; } break;
                    case 'symbol': { return Etype.symbol; } break;
                    case 'bigint': { return Etype.bigint; } break;
                    case 'number': { return Etype.number; } break;
                    case 'boolean': { return Etype.boolean; } break;
                    case 'string': { return Etype.string; } break;
                    case 'function': { return Etype.function; } break;
                    case 'object': {
                        if (obj === null) {
                            return Etype.null;
                        }

                        if (obj === DEFAULT) {
                            return Etype.DEFAULT;
                        }

                        if (typeof obj.constructor === 'undefined') {
                            return Etype.NULLOBJ;
                        }

                        if (obj.constructor === Object) {
                            return Etype.obj;
                        }

                        if (Array.isArray(obj)) {
                            return Etype.array;
                        }

                        if (obj instanceof HTMLElement) {
                            return Etype.HTMLElement;
                        }

                        return obj.constructor.name;
                    } break;
                }
            }
        }
    });
}
